#include "platform.h"

	# size of each hart's stack is 1024 bytes
	.equ	STACK_SIZE, 1024

	.global	_start

	.text
_start:
	# park harts with id != 0
	csrr	t0, mhartid		# read current hart id， 
# 读控制状态寄存器 (Control and Status Register Read). 伪指令(Pesudoinstruction), 
# 把控制状态寄存器 csr 的值写入 x[rd]，等同于 csrrs rd, csr, x0.
	mv	tp, t0			# keep CPU's hartid in its tp for later usage.
# mv rd, rs1 x[rd] = x[rs1]
# 移动(Move). 伪指令(Pseudoinstruction), RV32I and RV64I.
# 把寄存器 x[rs1]复制到 x[rd]中。实际被扩展为 addi rd, rs1, 0

	bnez	t0, park		# if we're not on the hart 0
					# we park the hart
# bnez rs1, offset
# 不等于零时分支 (Branch if Not Equal to Zero). 伪指令(Pesudoinstruction), RV32I and RV64I.
# 可视为 bne rs1, x0, offset.

	# Setup stacks, the stack grows from bottom to top, so we put the
	# stack pointer to the very end of the stack range.
	slli	t0, t0, 10		# shift left the hart id by 1024
# slli rd, rs1, shamt x[rd] = x[rs1] ≪ shamt
# 立即数逻辑左移(Shift Left Logical Immediate). 
# 把寄存器x[rs1]左移shamt位，空出的位置填入0，结果写入x[rd]。对于RV32I，仅当shamt[5]=0
# 时，指令才是有效的。
	la	sp, stacks + STACK_SIZE	# set the initial stack pointer
					# to the end of the first stack space
					la rd, symbol x[rd] = &symbol
# la rd, symbol 地址加载 (Load Address). 伪指令(Pseudoinstruction), x[rd] = &symbol 
# 将 symbol 的地址加载到 x[rd]中。当编译位置无关的代码时，它会被扩展为
	add	sp, sp, t0		# move the current hart stack pointer
					# to its place in the stack space
# c.add rd, rs2 x[rd] = x[rd] + x[rs2]
	j	start_kernel		# hart 0 jump to c

park:
	wfi # wfi 通知处理器目前没有任何有用的工作，所有它应该进入低功耗模式，
	j	park 

stacks:
	.skip	STACK_SIZE * MAXNUM_CPU # allocate space for all the harts stacks

	.end				# End of file
